package com.growthsee.framework.security.provider;

import com.growthsee.common.core.domain.model.LoginUser;
import com.growthsee.framework.security.token.WeixinAuthenticationToken;
import com.growthsee.framework.web.service.UserDetailsServiceImpl;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class WeixinAuthenticationProvider implements AuthenticationProvider {
    private UserDetailsServiceImpl userService;
    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();


    public WeixinAuthenticationProvider(UserDetailsServiceImpl userService){
        this.userService = userService;
    }
    public WeixinAuthenticationProvider(){ }


    /**
     * 登陆判断
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String openId = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName();
        LoginUser user = userService.loadUserByOpenId(openId);
        if (null == user) {
            throw new BadCredentialsException(this.messages.getMessage(HttpStatus.UNAUTHORIZED.value()+"","账户不存在"));
        }
        //检查用户状态（是否锁定，是否过期）
        //比对密码是否正确
        Collection<? extends GrantedAuthority> authorities = user.getPermissions().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
        WeixinAuthenticationToken result = new WeixinAuthenticationToken(user,null,authorities);
        copyDetails(authentication,result);
        result.setDetails(authentication.getDetails());
        //察除密码
        //登陆成功信息公布出去
        //this.eventPublisher.publishAuthenticationSuccess(result);
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        boolean assignableFrom = WeixinAuthenticationToken.class.isAssignableFrom(authentication);
        System.out.println(assignableFrom?this.getClass().getName() + "---supports":this.getClass().getName() + "---not-supports");
        return assignableFrom;
    }

    private Set<GrantedAuthority> listUserGrantedAuthorities(Long uid) {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        if (StringUtils.isEmpty(uid)) {
            return authorities;
        }
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        return authorities;
    }

    private void copyDetails(Authentication source, Authentication dest) {
        if (dest instanceof AbstractAuthenticationToken && dest.getDetails() == null) {
            AbstractAuthenticationToken token = (AbstractAuthenticationToken)dest;
            token.setDetails(source.getDetails());
        }

    }
}
